use std::io::{Read, Seek};
use std::path::Path;

use flate2::read::GzDecoder;
use indicatif::{ProgressBar, ProgressStyle};
use tar::Archive;

use crate::runtime::runtime::error::InternalError;
use crate::runtime::runtime::result::InternalErrorResult;
use crate::util::util::reader::proxy::Proxy;

/// 解压tar.gz文件
pub fn decompress<R: Read + Seek, P: AsRef<Path>>(rp: P, r: R, s: u64, t: P) -> InternalErrorResult<()> {
    println!("解压文件: {} -> {}", rp.as_ref().to_str().unwrap(), t.as_ref().to_str().unwrap());

    // 进度条
    let pb = ProgressBar::new(s);
    pb.set_style(ProgressStyle::with_template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes}").unwrap().progress_chars("=>-"));

    // reader proxy
    let proxy = Proxy::new(r, |us| pb.inc(us as u64));

    // gzip decoder
    let decoder = GzDecoder::new(proxy);

    // tar decoder
    let mut archive = Archive::new(decoder);

    archive.unpack(t).map_err(|e| InternalError::new(format!("Could not decompress tar.gz file: {}", e.to_string())))?;
    pb.finish();

    Ok(())
}

#[cfg(test)]
mod tests {
    use reqwest::Url;
    use tempfile;

    use crate::util::util::network;

    #[test]
    fn test_decompress_tar_gzip() {
        let url = Url::parse("https://gitee.com/Luna-CY/hui-hui/releases/download/v0.3.1/hui-hui_linux_aarch64_v0.3.1.tar.gz");
        assert_eq!(true, url.is_ok());

        let result = network::downloader::download(url.unwrap());
        assert_eq!(true, result.is_ok(), "下载文件失败: {}", result.unwrap_err());

        let (f, s) = result.unwrap();

        let temp_dir = tempfile::tempdir();
        assert_eq!(true, temp_dir.is_ok(), "创建临时文件夹失败: {}", temp_dir.unwrap_err());

        let result = super::decompress(f.path(), &f, s, temp_dir.unwrap().path());
        assert_eq!(true, result.is_ok(), "解压文件失败: {}", result.unwrap_err());
    }
}